/*
 * Copyright 2023-2025, Haiku Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 * 		François Revol <revol@free.fr>
 *
 * Copyright 2004, Axel Dörfler, axeld@pinc-software.de
 * Distributed under the terms of the MIT License.
 */

#include <KernelExport.h>

#include <boot/stage2.h>
#include <arch/smp.h>
#include <debug.h>
#include <int.h>

#include <cpu.h>
#include <arch/loongarch64/arch_kernel_args.h>

extern uint32 gPlatform;

// 龙芯平台SMP函数声明
extern status_t loongson_smp_init(kernel_args *args);
extern status_t loongson_smp_per_cpu_init(kernel_args *args, int32 cpuId);
extern void loongson_smp_send_multicast_ici(CPUSet &cpuSet);
extern void loongson_smp_send_ici(int32 targetCpu);
extern void loongson_smp_send_broadcast_ici();

status_t
arch_smp_init(kernel_args *args)
{
    dprintf("arch_smp_init()\n");
    
    // 根据平台类型调用相应的初始化函数
    switch (gPlatform) {
    case kPlatformLoongson:
        return loongson_smp_init(args);
    default:
        dprintf("arch_smp_init: unknown platform %u\n", gPlatform);
        return B_ERROR;
    }
}

status_t
arch_smp_per_cpu_init(kernel_args *args, int32 cpuId)
{
    // 根据平台类型调用相应的CPU初始化函数
    switch (gPlatform) {
    case kPlatformLoongson:
        return loongson_smp_per_cpu_init(args, cpuId);
    default:
        return B_ERROR;
    }
}

void arch_smp_send_multicast_ici(CPUSet &cpuSet)
{
#if KDEBUG
    if (are_interrupts_enabled())
        panic("arch_smp_send_multicast_ici: called with interrupts enabled");
#endif

    // 根据平台类型调用相应的多播IPI函数
    switch (gPlatform) {
    case kPlatformLoongson:
        loongson_smp_send_multicast_ici(cpuSet);
        break;
    default:
        dprintf("arch_smp_send_multicast_ici: not implemented for platform %u\n", gPlatform);
        break;
    }
}

void arch_smp_send_ici(int32 target_cpu)
{
    // 根据平台类型调用相应的单播IPI函数
    switch (gPlatform) {
    case kPlatformLoongson:
        loongson_smp_send_ici(target_cpu);
        break;
    default:
        dprintf("arch_smp_send_ici: not implemented for platform %u\n", gPlatform);
        break;
    }
}

void arch_smp_send_broadcast_ici()
{
    // 根据平台类型调用相应的广播IPI函数
    switch (gPlatform) {
    case kPlatformLoongson:
        loongson_smp_send_broadcast_ici();
        break;
    default:
        dprintf("arch_smp_send_broadcast_ici: not implemented for platform %u\n", gPlatform);
        break;
    }
}